﻿namespace _4_NovaAdmin.Web.Core.InjectionHub;

public static class InjectionSetup
{
    private static readonly ProxyGenerator _generator = new ProxyGenerator();

    /// <summary>
    /// 添加依赖注入相关的配置,即：IOC
    /// </summary>
    /// <param name="services"></param>
    /// <returns></returns>
    public static void AddInjection(this IServiceCollection services)
    {
        ArgumentNullException.ThrowIfNull(services);
        // 定义依赖接口与生命周期的映射关系
        Dictionary<Type, ServiceLifetime> lifeTimeMap = new Dictionary<Type, ServiceLifetime>
        {
            { typeof(ITransientDependency), ServiceLifetime.Transient},
            { typeof(IScopedDependency),ServiceLifetime.Scoped},
            { typeof(ISingletonDependency),ServiceLifetime.Singleton}
        };

        // 遍历所有程序集中的类
        GlobalAssemblies.AllTypes.ForEach(type =>
        {
            // 遍历依赖接口与生命周期的映射关系
            foreach (var (dependency, lifetime) in lifeTimeMap)
            {
                // 检查当前类是否实现了依赖接口，并且不是抽象类且是类  
                if (dependency.IsAssignableFrom(type) && dependency != type && !type.IsAbstract && type.IsClass)
                {
                    // 注入实现类，创建接口代理时要用到实例
                    services.Add(new ServiceDescriptor(type, type, lifetime));

                    // 获取当前类实现的所有接口（排除依赖接口）  
                    var interfaces = GlobalAssemblies.AllTypes
                        .Where(x => x.IsAssignableFrom(type) && x.IsInterface && x != dependency)
                        .ToList();

                    var hasInterfaces = interfaces.Any();
                    var serviceTypes = hasInterfaces ? interfaces.Cast<Type>().ToList() : new List<Type> { type };

                    foreach (var serviceType in serviceTypes)
                    {
                        services.AddProxyService(serviceType, type, lifetime, hasInterfaces);
                    }
                }
            }
        });
    }

    /// <summary>
    /// 添加代理服务
    /// </summary>
    /// <param name="services"></param>
    /// <param name="serviceType"></param>
    /// <param name="implementationType"></param>
    /// <param name="lifetime"></param>
    /// <param name="isInterface"></param>
    private static void AddProxyService(this IServiceCollection services, Type serviceType, Type implementationType, ServiceLifetime lifetime, bool isInterface = true)
    {
        services.Add(new ServiceDescriptor(serviceType, serviceProvider =>
        {
            var castleInterceptor = new CastleInterceptor(serviceProvider);
            if (isInterface)
            {
                // 创建接口代理实例
                var target = serviceProvider.GetRequiredService(implementationType);
                return _generator.CreateInterfaceProxyWithTarget(serviceType, target, castleInterceptor);
            }
            else
            {
                // 创建类代理实例 - 处理构造函数参数
                var constructorArgs = GetConstructorArguments(serviceProvider, implementationType);
                return _generator.CreateClassProxy(implementationType, constructorArgs, castleInterceptor);
            }
        }, lifetime));
    }

    /// <summary>
    /// 获取构造函数参数
    /// </summary>
    /// <param name="serviceProvider">服务提供者</param>
    /// <param name="type">要实例化的类型</param>
    /// <returns>构造函数参数数组</returns>
    private static object[] GetConstructorArguments(IServiceProvider serviceProvider, Type type)
    {
        // 获取参数最多的公共构造函数，按参数数量降序排列，取第一个  
        var constructor = type.GetConstructors().OrderByDescending(c => c.GetParameters().Length).FirstOrDefault();
        if (constructor == null)
        {
            return Array.Empty<object>();
        }

        // 获取构造函数参数并尝试从DI容器解析
        return constructor.GetParameters()
            .Select(p =>
            {
                return serviceProvider.GetRequiredService(p.ParameterType);
            })
            .ToArray();

        //// 获取构造函数参数并尝试从DI容器解析
        //return constructor.GetParameters()
        //    .Select(p =>
        //    {
        //        var parameterValue = serviceProvider.GetService(p.ParameterType);
        //        if (parameterValue == null)
        //        {
        //            if (p.HasDefaultValue)
        //            {
        //                return p.DefaultValue;
        //            }
        //            else
        //            {
        //                throw new InvalidOperationException(
        //                    $"无法解析类型 {type.FullName} 的构造函数参数 {p.Name} ({p.ParameterType.FullName})。" +
        //                    $"请确保该类型已注册到容器中。");
        //            }
        //        }
        //        return parameterValue;
        //    })
        //    .ToArray();
    }
}
